#include <iostream>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include "tcpserver.h"
#include "message_type_reader.h"
#include "appconfig_reader.h"
#include "loghelper.h"
#include "messagehandler.h"
#include "publish_image.h"

using namespace boost;
using boost::asio::ip::tcp;
using namespace RockLog;

int main(int argc, char *argv[])
{
    std::string tag = "cpp_server";
    LogHelper::initLogHelper(tag);
    try
    {
        // loadAppConfig
        const std::string cfgFilePath = boost::filesystem::current_path().string() + std::string("/cpp_server.cfg");
        ServerConfig_t cfg;
        if (boost::filesystem::exists(cfgFilePath))
            cfg = std::move(loadAppConfig(cfgFilePath));

        if (argc >= 2)
        {
            cfg.serverPort = std::atoi(argv[1]);
        }
        else
        {
            std::cout << "cfg.serverPort: " << cfg.serverPort << std::endl;
            std::cout << "!!!You can also input <port> on the terminal!!!\n";
        }

        // loadMessageTypes
        const std::string messageTypeFilePath = boost::filesystem::current_path().string() + std::string("/message_types.json");
        MessageType_t messageTypes;
        if (boost::filesystem::exists(messageTypeFilePath))
            messageTypes = loadMessageTypes(messageTypeFilePath);

        if (messageTypes.size() == 0)
        {
            LOG(kErr) << "[E] load message_types.json failed!" << std::endl;
            return -1;
        }

        boost::asio::io_context io_context;
        // prevent the io_context from returning when no more work to do
        auto work = boost::asio::make_work_guard(io_context);

        tcp::endpoint listen_endpoint(tcp::v4(), cfg.serverPort);
        MessageHandler messagehandler(messageTypes);
        PublishImage publishImage;
        std::thread t(&PublishImage::startPublish, &publishImage, "/home/dgliu/test/vipc_linux_x64/60s_1920_1080.h264");
        t.detach();

        TcpServer s(io_context, listen_endpoint, messageTypes, cfg, &messagehandler);

        io_context.run();

        LOG(kErr) << "the serverapp is exit!!" << std::endl;
    }
    catch (std::exception &e)
    {
        LOG(kErr) << "Exception: " << e.what() << "\n";
    }

    return 0;
}
